﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using WebCrawler.Model;
using WebCrawler.Service;

namespace WebCrawler.ViewModel
{
    public class WebKuleimanViewModel : ViewModelBase
    {
        public WebKuleimanViewModel()
        {
            initBaseData();
        }

        #region 属性
        // 基础URL
        public string Url
        {
            get { return _url; }
            set { _url = value; RaisePropertyChanged(() => Url); }
        }
        private string _url;

        // 全景图名
        public string Name
        {
            get { return _name; }
            set { _name = value; RaisePropertyChanged(() => Name); }
        }
        private string _name;

        // 瓦片组合的行列数
        public int Tile
        {
            get { return _tile; }
            set { _tile = value; RaisePropertyChanged(() => Tile); }
        }
        private int _tile;

        // 是否下载单个的小图
        public bool DownloadSingleImage
        {
            get { return _downloadSingleImage; }
            set { _downloadSingleImage = value; RaisePropertyChanged(() => DownloadSingleImage); }
        }
        private bool _downloadSingleImage;

        public bool IsDownloading
        {
            get { return _isDownloading; }
            set { _isDownloading = value; RaisePropertyChanged(() => IsDownloading); }
        }
        private bool _isDownloading = false;

        public string StepMessage
        {
            get { return _stepMessage; }
            set { _stepMessage = value; RaisePropertyChanged(() => StepMessage); }
        }
        private string _stepMessage;
        #endregion

        #region 命令
        public RelayCommand StartDownloadCmd
        {
            get
            {
                if (_startDownloadCmd == null)
                    _startDownloadCmd = new RelayCommand(startDownload, canStartDownload);
                return _startDownloadCmd;
            }
            set { _startDownloadCmd = value; }
        }
        public RelayCommand _startDownloadCmd;
        #endregion

        #region 辅助函数

        private void initBaseData()
        {
            DownloadSingleImage = false;
            Tile = 4;

            // 测试
            Url = "https://imj.kuleiman.com/119921/scene/scene152171/view/4352_";
            Tile = 9;
            Name = "南昌起义";
        }

        private async void startDownload()
        {
            string folderPath = $"{AppDomain.CurrentDomain.BaseDirectory}/{Name}";

            StepMessage = "开始";
            IsDownloading = true;

            await download(Url, Tile, folderPath, DownloadSingleImage);

            IsDownloading = false;
            StepMessage = "完成";
        }

        private bool canStartDownload()
        {
            return true;
        }

        private async Task download(string url, int tile, string folder, bool saveSingleImage)
        {
            string curTile = string.Empty;
            string curUrl = string.Empty;

            // 左上
            curTile = "1"; // _pano_f/klm_9klm9
            curUrl = $"{url}pano_f/klm_{curTile}klm{curTile}.jpg";
            StepMessage = $"计算左上角像素";
            Mat upperLeft = await ImageUtility.DownloadImageAsync(curUrl, "", false, "https://www.kuleiman.com/");

            // 右下
            curTile = tile.ToString();
            curUrl = $"{url}pano_f/klm_{curTile}klm{curTile}.jpg";
            StepMessage = $"计算右下角像素";
            Mat lowerRight = await ImageUtility.DownloadImageAsync(curUrl, "", false, "https://www.kuleiman.com/");

            Dictionary<string, Mat> mats = new Dictionary<string, Mat>();
            // 请求单张图片
            for (int i = 0; i < 6; i++)
            {
                string side = string.Empty;
                switch (i)
                {
                    case 0: side = "f"; break;
                    case 1: side = "b"; break;
                    case 2: side = "r"; break;
                    case 3: side = "l"; break;
                    case 4: side = "u"; break;
                    case 5: side = "d"; break;
                }

                Mat[,] matpArray = new Mat[tile, tile];

                for (int j = 0; j < tile; j++)
                {
                    for (int k = 0; k < tile; k++)
                    {
                        string row = (j + 1).ToString();
                        string col = (k + 1).ToString();

                        curUrl = $"{url}pano_{side}/klm_{row}klm{col}.jpg";
                        string fileName = $"{folder}/single/{side}_{row}_{col}.jpg";

                        StepMessage = $"下载：{curUrl}";
                        Mat mat = await ImageUtility.DownloadImageAsync(curUrl, fileName, saveSingleImage, "https://www.kuleiman.com/");

                        matpArray[j, k] = mat;
                    }
                }

                StepMessage = $"合并：{side}";
                Mat mat_Side = await ImageUtility.MergeSide(side, folder, matpArray, upperLeft.Size(), lowerRight.Size());
                mats[side] = mat_Side;
            }

            // 释放
            upperLeft.Dispose();
            lowerRight.Dispose();

            // 合并Cube
            StepMessage = $"合并：Cubemap";
            Mat cubemap = await ImageUtility.MergeCubemapAsync(folder, mats);

            // 转换全景图
            StepMessage = $"合并：Panorama";
            await ImageUtility.CubemapToPanoramaAsync(folder, cubemap);
        }
        #endregion
    }
}